#
#  Copyright 2024 The InfiniFlow Authors. All Rights Reserved.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#
import os
import os.path
import logging
from logging.handlers import RotatingFileHandler

initialized_root_logger = False

def get_project_base_directory():
    """
    os.path.realpath(__file__) 获取当前模块文件（.py）的真实路径（解决符号链接问题）
    os.path.dirname 当前文件夹utils
    os.pardir上一级目录，相当于../ -> api文件夹
    再来一个os.pardir上一级目录，相当于../ -> ragflow文件夹也就是根目录
    os.path.abspath(...)将相对路径转换为绝对路径，确保返回的路径格式统一且可靠。
    """
    PROJECT_BASE = os.path.abspath(
        os.path.join(
            os.path.dirname(os.path.realpath(__file__)),
            os.pardir,
            os.pardir,
        )
    )
    return PROJECT_BASE

# 定义初始化根日志记录器的函数，接收日志文件的基本名称和日志格式作为参数
def initRootLogger(logfile_basename: str, log_format: str = "%(asctime)-15s %(levelname)-8s %(process)d %(message)s"):
    # 声明全局变量 initialized_root_logger 用于确保只初始化一次
    global initialized_root_logger
    # 如果已经初始化过，则直接返回，避免重复初始化
    if initialized_root_logger:
        return
    # 标记为已初始化
    initialized_root_logger = True

    # 获取根日志记录器对象
    logger = logging.getLogger()
    # 清除已有的所有处理器(handler)，防止重复添加
    logger.handlers.clear()
    # 构建日志文件的完整路径，位于项目目录下的 logs 子目录中
    log_path = os.path.abspath(os.path.join(get_project_base_directory(), "logs", f"{logfile_basename}.log"))

    # 创建日志文件所在目录（如果不存在的话）
    os.makedirs(os.path.dirname(log_path), exist_ok=True)
    # 创建一个日志格式化器对象，使用指定的日志格式
    formatter = logging.Formatter(log_format)

    # 创建一个 RotatingFileHandler 处理器，用于写入日志文件，最大大小为10MB，保留最多5个备份文件
    handler1 = RotatingFileHandler(log_path, maxBytes=10*1024*1024, backupCount=5)
    # 设置该处理器的日志格式
    handler1.setFormatter(formatter)
    # 将该处理器添加到根日志记录器
    logger.addHandler(handler1)

    # 创建一个 StreamHandler 处理器，用于将日志输出到控制台
    handler2 = logging.StreamHandler()
    # 设置该处理器的日志格式
    handler2.setFormatter(formatter)
    # 将该处理器添加到根日志记录器
    logger.addHandler(handler2)

    # 捕获所有警告信息，并通过 logging 模块进行处理
    logging.captureWarnings(True)

    # 从环境变量 LOG_LEVELS 中获取日志级别配置字符串
    LOG_LEVELS = os.environ.get("LOG_LEVELS", "")
    # 初始化一个字典用于存储各个模块对应的日志级别
    pkg_levels = {}
    # 遍历环境变量中的每个包名=日志级别的配置项
    for pkg_name_level in LOG_LEVELS.split(","):
        # 分割包名和日志级别
        terms = pkg_name_level.split("=")
        # 如果不是标准的 key=value 形式则跳过
        if len(terms)!= 2:
            continue
        # 提取包名和日志级别
        pkg_name, pkg_level = terms[0], terms[1]
        # 去除两端空格
        pkg_name = pkg_name.strip()
        # 去除两端空格并将日志级别转为大写
        pkg_level = logging.getLevelName(pkg_level.strip().upper())
        # 如果转换失败，默认使用 INFO 级别
        if not isinstance(pkg_level, int):
            pkg_level = logging.INFO
        # 存储解析后的日志级别
        pkg_levels[pkg_name] = logging.getLevelName(pkg_level)

    # 为特定模块 peewee 和 pdfminer 设置默认日志级别为 WARNING
    for pkg_name in ['peewee', 'pdfminer']:
        if pkg_name not in pkg_levels:
            pkg_levels[pkg_name] = logging.getLevelName(logging.WARNING)
    # 如果未设置 root 的日志级别，则默认设置为 INFO
    if 'root' not in pkg_levels:
        pkg_levels['root'] = logging.getLevelName(logging.INFO)

    # 遍历所有指定的模块，设置其对应日志级别
    for pkg_name, pkg_level in pkg_levels.items():
        # 获取对应的日志记录器
        pkg_logger = logging.getLogger(pkg_name)
        # 设置日志级别
        pkg_logger.setLevel(pkg_level)

    # 输出日志路径和日志级别配置信息
    msg = f"{logfile_basename} log path: {log_path}, log levels: {pkg_levels}"
    logger.info(msg)